home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 41 / Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso / -seriously_amiga- / misc / xpdf_0.8 / xpdf_src / goo / gmem.c < prev    next >
C/C++ Source or Header  |  1999-04-28  |  3KB  |  183 lines

  1. /*
  2.  * gmem.c
  3.  *
  4.  * Memory routines with out-of-memory checking.
  5.  *
  6.  * Copyright 1996 Derek B. Noonburg
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <stddef.h>
  12. #include <string.h>
  13. #include "gmem.h"
  14.  
  15. #ifdef DEBUG_MEM
  16. typedef struct _GMemHdr {
  17.   int size;
  18.   int index;
  19.   struct _GMemHdr *next;
  20. } GMemHdr;
  21.  
  22. #define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
  23. #define gMemTrlSize (sizeof(long))
  24.  
  25. #if gmemTrlSize==8
  26. #define gMemDeadVal 0xdeadbeefdeadbeef
  27. #else
  28. #define gMemDeadVal 0xdeadbeef
  29.  
  30. /* round data size so trailer will be aligned */
  31. #define gMemDataSize(size) \
  32.   ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
  33.  
  34. #endif
  35.  
  36. static GMemHdr *gMemList = NULL;
  37. static int gMemIndex = 0;
  38. static int gMemAlloc = 0;
  39. #endif
  40.  
  41. void *gmalloc(int size) {
  42. #if DEBUG_MEM
  43.   int size1;
  44.   char *mem;
  45.   GMemHdr *hdr;
  46.   void *data;
  47.   long *trl, *p;
  48.  
  49.   if (size == 0)
  50.     return NULL;
  51.   size1 = gMemDataSize(size);
  52.   if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
  53.     fprintf(stderr, "Out of memory\n");
  54.     exit(1);
  55.   }
  56.   hdr = (GMemHdr *)mem;
  57.   data = (void *)(mem + gMemHdrSize);
  58.   trl = (long *)(mem + gMemHdrSize + size1);
  59.   hdr->size = size;
  60.   hdr->index = gMemIndex++;
  61.   hdr->next = gMemList;
  62.   gMemList = hdr;
  63.   ++gMemAlloc;
  64.   for (p = (long *)data; p <= trl; ++p)
  65.     *p = gMemDeadVal;
  66.   return data;
  67. #else
  68.   void *p;
  69.  
  70.   if (size == 0)
  71.     return NULL;
  72.   if (!(p = malloc(size))) {
  73.     fprintf(stderr, "Out of memory\n");
  74.     exit(1);
  75.   }
  76.   return p;
  77. #endif
  78. }
  79.  
  80. void *grealloc(void *p, int size) {
  81. #if DEBUG_MEM
  82.   GMemHdr *hdr;
  83.   void *q;
  84.   int oldSize;
  85.  
  86.   if (size == 0) {
  87.     if (p)
  88.       gfree(p);
  89.     return NULL;
  90.   }
  91.   if (p) {
  92.     hdr = (GMemHdr *)((char *)p - gMemHdrSize);
  93.     oldSize = hdr->size;
  94.     q = gmalloc(size);
  95.     memcpy(q, p, size < oldSize ? size : oldSize);
  96.     gfree(p);
  97.   } else {
  98.     q = gmalloc(size);
  99.   }
  100.   return q;
  101. #else
  102.   void *q;
  103.  
  104.   if (size == 0) {
  105.     if (p)
  106.       free(p);
  107.     return NULL;
  108.   }
  109.   if (p)
  110.     q = realloc(p, size);
  111.   else
  112.     q = malloc(size);
  113.   if (!q) {
  114.     fprintf(stderr, "Out of memory\n");
  115.     exit(1);
  116.   }
  117.   return q;
  118. #endif
  119. }
  120.  
  121. void gfree(void *p) {
  122. #ifdef DEBUG_MEM
  123.   int size;
  124.   GMemHdr *hdr;
  125.   GMemHdr *prevHdr, *q;
  126.   long *trl, *clr;
  127.  
  128.   if (p) {
  129.     hdr = (GMemHdr *)((char *)p - gMemHdrSize);
  130.     for (prevHdr = NULL, q = gMemList; q; prevHdr = q, q = q->next) {
  131.       if (q == hdr)
  132.     break;
  133.     }
  134.     if (q) {
  135.       if (prevHdr)
  136.     prevHdr->next = hdr->next;
  137.       else
  138.     gMemList = hdr->next;
  139.       --gMemAlloc;
  140.       size = gMemDataSize(hdr->size);
  141.       trl = (long *)((char *)hdr + gMemHdrSize + size);
  142.       if (*trl != gMemDeadVal) {
  143.     fprintf(stderr, "Overwrite past end of block %d at address %p\n",
  144.         hdr->index, p);
  145.       }
  146.       for (clr = (long *)hdr; clr <= trl; ++clr)
  147.     *clr = gMemDeadVal;
  148.       free(hdr);
  149.     } else {
  150.       fprintf(stderr, "Attempted to free bad address %p\n", p);
  151.     }
  152.   }
  153. #else
  154.   if (p)
  155.     free(p);
  156. #endif
  157. }
  158.  
  159. #ifdef DEBUG_MEM
  160. void gMemReport(FILE *f) {
  161.   GMemHdr *p;
  162.  
  163.   fprintf(f, "%d memory allocations in all\n", gMemIndex);
  164.   if (gMemAlloc > 0) {
  165.     fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
  166.     fprintf(f, " index     size\n");
  167.     fprintf(f, "-------- --------\n");
  168.     for (p = gMemList; p; p = p->next)
  169.       fprintf(f, "%8d %8d\n", p->index, p->size);
  170.   } else {
  171.     fprintf(f, "No memory blocks left allocated\n");
  172.   }
  173. }
  174. #endif
  175.  
  176. char *copyString(char *s) {
  177.   char *s1;
  178.  
  179.   s1 = (char *)gmalloc(strlen(s) + 1);
  180.   strcpy(s1, s);
  181.   return s1;
  182. }
  183.